package com.cheyunkeji.er.service;

import android.text.TextUtils;
import android.util.Log;

import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.GetObjectRequest;
import com.alibaba.sdk.android.oss.model.GetObjectResult;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.cheyunkeji.er.utils.ChannelInfoUtil;
import com.cheyunkeji.er.utils.PictureCompressUtil;
import com.cheyunkeji.er.utils.TimeUtils;
import com.cheyunkeji.er.view.SToast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;

/**
 * Created by oss on 2015/12/7 0007.
 * 支持普通上传，普通下载和断点上传
 */
public class OssService {

    //根据实际需求改变分片大小
    private final static int partSize = 256 * 1024;
    private static final String TAG = OssService.class.getSimpleName();

    private OSS oss;
    private String bucket;
    private String callbackAddress;
    private onImageProcessedResultListener resultListener;

    public OssService(OSS oss ,String bucket ){
        this.oss = oss ;
        this.bucket = bucket ;
    }

    public OssService(OSS oss, String bucket, onImageProcessedResultListener resultListener) {
        this.oss = oss;
        this.bucket = bucket;
        this.resultListener = resultListener;
        setOnImageProcessedResultListener(resultListener);
    }

    public void SetBucketName(String bucket) {
        this.bucket = bucket;
    }

    public void InitOss(OSS _oss) {
        this.oss = _oss;
    }

    public void setCallbackAddress(String callbackAddress) {
        this.callbackAddress = callbackAddress;
    }


    /**
     * 异步下载图片
     *
     * @param object
     */
    public void asyncGetImage(String object) {

        if ((object == null) || object.equals("")) {
            Log.w("AsyncGetImage", "ObjectNull");
            return;
        }

        GetObjectRequest get = new GetObjectRequest(bucket, object);

        OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
            @Override
            public void onSuccess(GetObjectRequest request, GetObjectResult result) {
                // 请求成功
                InputStream inputStream = result.getObjectContent();
                //重载InputStream来获取读取进度信息
                ProgressInputStream progressStream = new ProgressInputStream(inputStream, new OSSProgressCallback<GetObjectRequest>() {
                    @Override
                    public void onProgress(GetObjectRequest o, long currentSize, long totalSize) {
                        Log.d("GetObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
                        int progress = (int) (100 * currentSize / totalSize);
//                        UIDisplayer.updateProgress(progress);
//                        UIDisplayer.displayInfo("下载进度: " + String.valueOf(progress) + "%");
                    }
                }, result.getContentLength());

                //Bitmap bm = BitmapFactory.decodeStream(inputStream);
                //需要根据对应的View大小来自适应缩放
//                    Bitmap bm = UIDisplayer.autoResizeFromStream(progressStream);
//                    UIDisplayer.downloadComplete(bm);
//                    UIDisplayer.displayInfo("Bucket: " + bucket + "\nObject: " + request.getObjectKey() + "\nRequestId: " + result.getRequestId());
            }

            @Override
            public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                String info = "";
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                    SToast.show(clientExcepion.toString());
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                    info = serviceException.toString();
                }
            }
        });
    }


    /**
     *  同步上传图片
     * @param object  文件标识
     * @param localFilePath 文件路径
     * @param tag   标签
     * @return      OSS 云存储文件路径
     */
    public OssUnit synchronizePutImage(String object, String localFilePath , Object tag) throws ClientException, ServiceException {
        if (TextUtils.isEmpty(object)) {
            throw new IllegalArgumentException("Object is null");
        }

        File file = new File(localFilePath);
        if (!file.exists()) {
            try {
                throw new FileNotFoundException(" The file waitting for upload is not exist!");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        String ossPath = null;
//        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, object, PictureCompressUtil.compressImageReturnAsByteArray(localFilePath, 30));
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, object,localFilePath );
        PutObjectResult result;
        result = oss.putObject(putObjectRequest);
        Log.e(TAG, "synchronizePutImage: OSS 图片同步上传结果" + "\n ETag :  "
                + result.getETag() + "\n StatusCode : " + result.getStatusCode() + "\n ServerCallbackReturnBody : "
                + result.getServerCallbackReturnBody());
        ossPath = getOutSideUrl(object, bucket);

        return new OssUnit(ossPath, tag);
    }

    /**
     * 异步上传图片
     *
     * @param object
     * @param localFile
     */
    public void asyncPutImage(final String object, String localFile, final Object tag) {
        if (object.equals("")) {
            Log.e("AsyncPutImage", "ObjectNull");
            return;
        }

        File file = new File(localFile);
        if (!file.exists()) {
            Log.e("AsyncPutImage", "FileNotExist");
            Log.e("LocalFile", localFile);
            return;
        }

        // 构造上传请求-原图上传
//        PutObjectRequest put = new PutObjectRequest(bucket, object,localFile );

//        图片压缩后上传
        PutObjectRequest put = new PutObjectRequest(bucket, object, PictureCompressUtil.compressImageReturnAsByteArray(localFile, 30));

//        if (callbackAddress != null) {
//            // 传入对应的上传回调参数，这里默认使用OSS提供的公共测试回调服务器地址
//            put.setCallbackParam(new HashMap<String, String>() {
//                {
//                    put("callbackUrl", callbackAddress);
//                    //callbackBody可以自定义传入的信息
//                    put("callbackBody", "filename=${object}");
//                }
//            });
//        }

        // 异步上传时可以设置进度回调
        put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
            @Override
            public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
                //Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
                int progress = (int) (100 * currentSize / totalSize);
//                UIDisplayer.updateProgress(progress);
//                UIDisplayer.displayInfo("上传进度: " + String.valueOf(progress) + "%");
            }
        });

        OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
            @Override
            public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                Log.e("PutObject", "UploadSuccess");
                Log.e("ETag", result.getETag());
                Log.e("RequestId", result.getRequestId());
                Log.e("nCallback", "onSuccess: " + result.getServerCallbackReturnBody());
                if (null != resultListener) {
                    resultListener.onUploadOk(getOutSideUrl(object, bucket), tag);
                }
                Log.e(TAG, "onSuccess: " + request.getObjectKey());
            }

            @Override
            public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
                String info = "";
                // 请求异常
                if (clientExcepion != null) {
                    // 本地异常如网络异常等
                    clientExcepion.printStackTrace();
                    SToast.show(clientExcepion.toString());
                }
                if (serviceException != null) {
                    // 服务异常
                    Log.e("ErrorCode", serviceException.getErrorCode());
                    Log.e("RequestId", serviceException.getRequestId());
                    Log.e("HostId", serviceException.getHostId());
                    Log.e("RawMessage", serviceException.getRawMessage());
                    SToast.show(serviceException.toString());
                }
                if (null != resultListener) {
                    resultListener.onUploadFailed();
                }
            }
        });
    }

    private String getOutSideUrl(String object, String bucket) {
        return new StringBuffer().append("http://").append(bucket).append(".oss-cn-hangzhou.aliyuncs.com/").append(object).toString();
    }

    public static String getOssObjectInfo(boolean hasChannel) {
        if (hasChannel) {
            return new StringBuffer().append(ChannelInfoUtil.getCurrentChannelInfo().getChannel()).append("/").
                    append(TimeUtils.millis2StringYY_MM(System.currentTimeMillis())).append("/").append(TimeUtils.millis2StringWithoutHMS(System.currentTimeMillis())).append("/").append(String.valueOf(System.currentTimeMillis())).append(".jpg").toString();
        } else {
            return new StringBuffer().
                    append(TimeUtils.millis2StringYY_MM(System.currentTimeMillis())).append("/").append(TimeUtils.millis2StringWithoutHMS(System.currentTimeMillis())).append("/").append(String.valueOf(System.currentTimeMillis())).append(".jpg").toString();
        }
    }

    public void setOnImageProcessedResultListener(onImageProcessedResultListener listener) {
        this.resultListener = listener;
    }

    public interface onImageProcessedResultListener {
        void onUploadOk(String imgUrl, Object tag);
        void onUploadFailed();
    }


    public static class OssUnit{
        private String path ;
        private Object tag ;

        public OssUnit(String path, Object tag) {
            this.path = path;
            this.tag = tag;
        }

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }

        public Object getTag() {
            return tag;
        }

        public void setTag(String tag) {
            this.tag = tag;
        }

        @Override
        public String toString() {
            return "OssUnit{" +
                    "path='" + path + '\'' +
                    ", tag=" + tag +
                    '}';
        }
    }

}
